package exporter

import (
	"github.com/prometheus/client_golang/prometheus"
	"io/ioutil"
	"log"
	"os/exec"
	"strings"
	"time"
)

type StoragePool struct {
	Name                             string
	PoolName                         string
	PoolID                           string
	RaidType                         string
	PercentFullThreshold             string
	Description                      string
	DiskType                         string
	State                            string
	Status                           string
	CurrentOperation                 string
	CurrentOperationState            string
	CurrentOperationStatus           string
	CurrentOperationPercentCompleted string
	RawCapacityBlocks                string
	RawCapacityGBs                   string
	UserCapacityBlocks               string
	UserCapacityGBs                  string
	ConsumedCapacityBlocks           string
	ConsumedCapacityGBs              string
	AvailableCapacityBlocks          string
	AvailableCapacityGBs             string
	PercentFull                      string
	TotalSubscribedCapacityBlocks    string
	TotalSubscribedCapacityGBs       string
	PercentSubscribed                string
	OversubscribedByBlocks           string
	OversubscribedByGBs              string
	Disks                            string
	LUNs                             string
}

var (
	storagePool = prometheus.NewGaugeVec(
		prometheus.GaugeOpts{
			Name: "vnx_get_all_storage_pool",
			Help: "Get All Storage Pool Info",
		},
		[]string{
			"Name",
			"PoolName",
			"PoolID",
			"RaidType",
			"PercentFullThreshold",
			"Description",
			"DiskType",
			"State",
			"Status",
			"CurrentOperation",
			"CurrentOperationState",
			"CurrentOperationStatus",
			"CurrentOperationPercentCompleted",
			"RawCapacityBlocks",
			"RawCapacityGBs",
			"UserCapacityBlocks",
			"UserCapacityGBs",
			"ConsumedCapacityBlocks",
			"ConsumedCapacityGBs",
			"AvailableCapacityBlocks",
			"AvailableCapacityGBs",
			"PercentFull",
			"TotalSubscribedCapacityBlocks",
			"TotalSubscribedCapacityGBs",
			"PercentSubscribed",
			"OversubscribedByBlocks",
			"OversubscribedByGBs",
			"Disks",
			"LUNs",
		},
	)
)

func StoragePoolGauge() *prometheus.GaugeVec {
	return storagePool
}

func GetStoragePoolMetrics(spIp string, user string, password string) {
	for {
		cmd := exec.Command("bash", "-c", "/opt/Navisphere/bin/naviseccli -h "+spIp+" -user "+user+" -password "+password+" -Scope 0 storagepool -list")
		stdout, _ := cmd.StdoutPipe()
		defer stdout.Close()
		if err := cmd.Start(); err != nil {
			log.Fatalf("cmd.Start: %v", err)
		}
		result, _ := ioutil.ReadAll(stdout) // 读取输出结果
		resData := string(result)

		hostList := strings.Split(resData, "\n\n")
		for _, hostString := range hostList {
			hostItems := strings.Split(hostString, "\n")
			data := new(StoragePool)
			for _, hostItem := range hostItems {
				if hostItem == "" {
					continue
				}
				if strings.Contains(hostItem, "Bus") {
					diskString := strings.Replace(hostItem, "\n", ";", -1)
					data.Disks = data.Disks + diskString
					continue
				}
				value := hostItem[strings.Index(hostItem, ":")+1 : strings.Count(hostItem, "")-1]
				value = strings.Replace(value, "  ", "", -1)
				if strings.Contains(hostItem, "Pool Name:") {
					data.Name = value
					data.PoolName = value
				} else if strings.Contains(hostItem, "Pool ID:") {
					data.PoolID = value
				} else if strings.Contains(hostItem, "Raid Type:") {
					data.RaidType = value
				} else if strings.Contains(hostItem, "Percent Full Threshold:") {
					data.PercentFullThreshold = value
				} else if strings.Contains(hostItem, "Description:") {
					data.Description = value
				} else if strings.Contains(hostItem, "Disk Type:") {
					data.DiskType = value
				} else if strings.Contains(hostItem, "State:") {
					data.State = value
				} else if strings.Contains(hostItem, "Status:") {
					data.Status = value
				} else if strings.Contains(hostItem, "Current Operation:") {
					data.CurrentOperation = value
				} else if strings.Contains(hostItem, "Current Operation State:") {
					data.CurrentOperationState = value
				} else if strings.Contains(hostItem, "Current Operation Status:") {
					data.CurrentOperationStatus = value
				} else if strings.Contains(hostItem, "Current Operation Percent Completed:") {
					data.CurrentOperationPercentCompleted = value
				} else if strings.Contains(hostItem, "Raw Capacity (Blocks):") {
					data.RawCapacityBlocks = value
				} else if strings.Contains(hostItem, "Raw Capacity (GBs):") {
					data.RawCapacityGBs = value
				} else if strings.Contains(hostItem, "User Capacity (Blocks):") {
					data.UserCapacityBlocks = value
				} else if strings.Contains(hostItem, "User Capacity (GBs):") {
					data.UserCapacityGBs = value
				} else if strings.Contains(hostItem, "Consumed Capacity (Blocks):") {
					data.ConsumedCapacityBlocks = value
				} else if strings.Contains(hostItem, "Consumed Capacity (GBs):") {
					data.ConsumedCapacityGBs = value
				} else if strings.Contains(hostItem, "Available Capacity (Blocks):") {
					data.AvailableCapacityBlocks = value
				} else if strings.Contains(hostItem, "Available Capacity (GBs):") {
					data.AvailableCapacityGBs = value
				} else if strings.Contains(hostItem, "Percent Full") {
					data.PercentFull = value
				} else if strings.Contains(hostItem, "Total Subscribed Capacity (Blocks):") {
					data.TotalSubscribedCapacityBlocks = value
				} else if strings.Contains(hostItem, "Total Subscribed Capacity (GBs):") {
					data.TotalSubscribedCapacityGBs = value
				} else if strings.Contains(hostItem, "Percent Subscribed:") {
					data.PercentSubscribed = value
				} else if strings.Contains(hostItem, "Oversubscribed by (Blocks):") {
					data.OversubscribedByBlocks = value
				} else if strings.Contains(hostItem, "Oversubscribed by (GBs):") {
					data.OversubscribedByGBs = value
				} else if strings.Contains(hostItem, "LUNs:") {
					data.LUNs = value
				}
			}
			if data.Name != "" {
				storagePool.WithLabelValues(
					data.Name,
					data.PoolName,
					data.PoolID,
					data.RaidType,
					data.PercentFullThreshold,
					data.Description,
					data.DiskType,
					data.State,
					data.Status,
					data.CurrentOperation,
					data.CurrentOperationState,
					data.CurrentOperationStatus,
					data.CurrentOperationPercentCompleted,
					data.RawCapacityBlocks,
					data.RawCapacityGBs,
					data.UserCapacityBlocks,
					data.UserCapacityGBs,
					data.ConsumedCapacityBlocks,
					data.ConsumedCapacityGBs,
					data.AvailableCapacityBlocks,
					data.AvailableCapacityGBs,
					data.PercentFull,
					data.TotalSubscribedCapacityBlocks,
					data.TotalSubscribedCapacityGBs,
					data.PercentSubscribed,
					data.OversubscribedByBlocks,
					data.OversubscribedByGBs,
					data.Disks,
					data.LUNs,
				)
			}
		}
		time.Sleep(60 * time.Second)
	}
}
